'''
Author: xubing
Date: 2021-06-01 21:56:13
LastEditTime: 2021-06-07 15:08:30
LastEditors: xubing
Description: 根据一串地址匹配出两级行政区
FilePath: \my_gists\ML\match_address.py
'''
import re
import pandas as pd
import jieba
import logging
import warnings
jieba.setLogLevel(logging.INFO)
warnings.filterwarnings('ignore')

class MatchAddr:
    def __init__(self):
        super(MatchAddr,self).__init__()
        self.region_df = pd.read_csv('ML/city',sep=',')

        self.prov = self.region_df['province_name'].values.tolist()
        self.city = self.region_df['city_name'].values.tolist()
        self.area = self.region_df['area_name'].values.tolist()


    def _zxs_check(self, p):
        flag = False
        zxs = ['北京市','天津市','重庆市','上海市'] # 4个直辖市特殊处理
        if p is not None and p in zxs:
            out = '%s-%s' % (p, p)
            flag = True
            return flag, out
        return flag, p
    def match_address(self,str):
        # PATTERN = r'([\u4e00-\u9fa5]{2,6}?(?:省|自治区)){0,1}[-|\s]*([\u4e00-\u9fa5]{2,7}?(?:市|区|县|州)){0,1}'

        #-----------------------------Start---------------------------------------
        # 似河北石家庄，河南郑州，河南平舆这样的字符串，但这些必须在字符串的开头
        # *******谨慎使用start到end的代码********
        # *******谨慎使用start到end的代码********
        # *******谨慎使用start到end的代码********

        if not any(x in str for x in ['省','自治区', '市','区','县','州']):
            # 如果字符串中不包含 '省','自治区', '市','区','县','州' 这些，直接进入这个分支
            cc = list(jieba.cut(str))[:2]
            # 空列表检查
            if len(cc) == 0: 
                return str
            p1,p2='',''
            for x in self.prov:
                if re.match(cc[0], x) is not None:
                    p1 = x
            # 增加个判断
            if len(cc)==2:
                for x in self.city:
                    if re.match(cc[1],x) is not None:
                        p2 = x
                for x in self.area:
                    if re.match(cc[1],x) is not None:
                        p2 = self.region_df['city_name'][self.region_df['area_name'] == x].values[0]
            if p1 == '' and p2 !='':
                p2 = ''
            return p1 + '-' + p2
          
        #-----------------------------End---------------------------------------
        
            

        PATTERN = r'([\S]{2,6}?(?:省|自治区)){0,1}[-|\s]*([\S]{2,7}?(?:市|区|县|州)){0,1}'
        pattern = re.compile(PATTERN)
        m = pattern.search(str)
        

        if not m.lastindex:
            return '' + '-' + ''
        p1, p2 = '', ''
        if m.lastindex >= 1:
            p1 = m.group(1)
            if p1 is not None and p1 not in self.prov:
                # 是否是标准的省份名称,如果不是转化为标准的省份名称
                # 否则为''
                for x in self.prov:
                    if re.match(p1[:-1], x) is not None:
                        p1 = x
                if p1 not in self.prov:
                    # 如果还是没有变成标准的，则用jieba分词解决
                    p1 = list(jieba.cut(p1))[-1]
            flag, out = self._zxs_check(p1)
            if flag:
                return out

                        

        if m.lastindex >= 2:
            p2 = m.group(2)
            # 对p2做检查
            # 是否是标准的城市名称 或 是否是标准的区县名称
            if p2 is not None:
                if p2 in self.city:  # 标准的城市
                    p2 = p2
                elif p2 in self.area:  # 标准的县
                    p2 = self.region_df['city_name'][self.region_df['area_name'] == p2].values[0]
                else:
                    p2 = list(jieba.cut(p2))[-1]

                    # 加判断
                    flag, out = self._zxs_check(p2)
                    if flag:
                        return out

                    if p2 in self.city:  # 标准的城市
                        p2 = p2
                    elif p2 in self.area:  # 标准的县
                        p2 = self.region_df['city_name'][self.region_df['area_name'] == p2].values[0]
                    else:
                        p2 = ''
            flag, out = self._zxs_check(p2)
            if flag:
                return out
                
        
        
        # 这里如果p1空的话，还可以用p2的信息来补充，但p2空的话就没有办法补充了
        if p1 is None and p2 != '':
            p1 = self.region_df['province_name'][self.region_df['city_name'] == p2].values[0]

    
        if p1 is None:
            p1 = ''
 
        out = '%s-%s' % (p1, p2)
        return out

if __name__ == '__main__':

    data_list = ['上山打老虎',
                '翼城县里砦镇郑比村东街24号',
                '新疆省昌吉市',
                '福建省-漳州市-平和县',
                '武汉武昌区水果湖街道中北路 中北春天31001',
                '安徽省马鞍山市安徽省马鞍山市当涂县013县道',
                '山东省聊城市河北省沧州市黄骅市北京中医药大学东方学院渤海校区',
                '北京市通县',
                '北京市通州',
                '北京市怀柔区',
                '蚌埠市xxxx',
                '河北石家庄',
                '四平市铁西区',
                '你好呀河南潢川县',
                '北京北京市丰台区',
                '你好市民',
                '你好',
                '大义镇',
                '河南省',
                '北京',
                '北京'
                ]

    Ma = MatchAddr()
    for data in data_list:
        print(Ma.match_address(data))

    # print(Ma.match_address('大义镇'))